using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Xml.Linq;
using Engine;
using LiteNetLib;
using LiteNetLib.Utils;

namespace Game
{
	public class LJGameLoadingScreen : Screen
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class _003C_003Ec
		{
			public static readonly _003C_003Ec _003C_003E9 = new _003C_003Ec();

			public static EventBasedNetListener.OnNetworkError _003C_003E9__3_3;

			internal void _003C_002Ector_003Eb__3_3(IPEndPoint ep, SocketError err)
			{
				NetworkManager.ClientStage = NetworkManager.PeerStage.Invalid;
				ScreensManager.SwitchScreen("MainMenu");
				Log.Error(err);
				DialogsManager.ShowDialog(null, new MessageDialog("Network Error", err.ToString(), "OK", null, null));
			}
		}

		private string m_downloadedWorld;

		private IPEndPoint m_serverEndPoint;

		private StateMachine m_stateMachine = new StateMachine();

		public LJGameLoadingScreen()
		{
			XElement xElement = ContentManager.Get<XElement>("Screens/GameLoadingScreen");
			WidgetsManager.LoadWidgetContents((Widget)this, (object)this, xElement);
			m_stateMachine.AddState("WaitingForFadeIn", null, new Action(_003C_002Ector_003Eb__3_0), null);
			m_stateMachine.AddState("Loading", null, new Action(_003C_002Ector_003Eb__3_1), null);
			m_stateMachine.AddState("Connecting", new Action(_003C_002Ector_003Eb__3_2), null, null);
		}

		public override void Update()
		{
			try
			{
				m_stateMachine.Update();
			}
			catch (Exception ex)
			{
				NetworkManager.Listener.PeerDisconnectedEvent -= new EventBasedNetListener.OnPeerDisconnected(PeerDisconnectedEvent);
				NetworkManager.Manager.DisconnectAll();
				ScreensManager.SwitchScreen(ScreensManager.PreviousScreen);
				Log.Error(ex);
				DialogsManager.ShowDialog(null, new MessageDialog("Error loading client world", ExceptionManager.MakeFullErrorMessage(ex), "OK", null, null));
			}
		}

		public override void Enter(object[] parameters)
		{
			m_serverEndPoint = parameters[0] as IPEndPoint;
			m_stateMachine.TransitionTo("WaitingForFadeIn");
			NetworkManager.PeerStateChanged += new Action<NetPeer>(PeerStateChanged);
			NetworkManager.Listener.PeerDisconnectedEvent += new EventBasedNetListener.OnPeerDisconnected(PeerDisconnectedEvent);
			NetworkManager.SubscribePacket(new Action<WorldFilePacket, NetPeer>(NetworkReceiveEvent));
		}

		public override void Leave()
		{
			NetworkManager.Listener.PeerDisconnectedEvent -= new EventBasedNetListener.OnPeerDisconnected(PeerDisconnectedEvent);
			NetworkManager.RemoveSubscribtion<WorldFilePacket>();
		}

		private void NetworkReceiveEvent(WorldFilePacket packet, NetPeer peer)
		{
			Log.Information("recived world file");
			using (Stream s = new MemoryStream(packet.WorldFile))
			{
				m_downloadedWorld = LJGameManager.ImportClientWorld(s);
			}
			m_stateMachine.TransitionTo("Loading");
		}

		private void PeerStateChanged(NetPeer peer)
		{
			if (peer.EndPoint == m_serverEndPoint)
			{
				if (NetworkManager.GetData(peer).PeerStage != NetworkManager.PeerStage.Ready)
				{
					Log.Information("Server is not ready");
					NetDataWriter netDataWriter = new NetDataWriter();
					netDataWriter.Put("Server not ready");
					peer.Disconnect(netDataWriter);
				}
				NetworkManager.PeerStateChanged -= new Action<NetPeer>(PeerStateChanged);
			}
		}

		private void PeerDisconnectedEvent(NetPeer peer, DisconnectInfo info)
		{
			if (peer.EndPoint == m_serverEndPoint)
			{
				NetworkManager.ClientStage = NetworkManager.PeerStage.Invalid;
				ScreensManager.SwitchScreen("MainMenu");
				string result;
				if (!info.AdditionalData.TryGetString(out result))
				{
					result = info.Reason.ToString();
				}
				Log.Error("Disconnected: " + result);
				DialogsManager.ShowDialog(null, new MessageDialog("Disconnected", result, "OK", null, null));
			}
		}

		[CompilerGenerated]
		private void _003C_002Ector_003Eb__3_0()
		{
			if (!ScreensManager.IsAnimating)
			{
				m_stateMachine.TransitionTo("Connecting");
			}
		}

		[CompilerGenerated]
		private void _003C_002Ector_003Eb__3_1()
		{
			ContainerWidget containerWidget = ScreensManager.FindScreen<GameScreen>("Game").Children.Find<ContainerWidget>("GamesWidget");
			GameManager.LoadProject(WorldsManager.GetWorldInfo(m_downloadedWorld), containerWidget);
			LJGameManager.DisableUpdatables(GameManager.Project);
			int num = 0;
			SubsystemRemotePlayers subsystemRemotePlayers = GameManager.Project.FindSubsystem<SubsystemRemotePlayers>(true);
			foreach (PlayerData playersDatum in GameManager.Project.FindSubsystem<SubsystemPlayers>(true).PlayersData)
			{
				if (subsystemRemotePlayers.IsMainPlayer(playersDatum))
				{
					num++;
					playersDatum.InputDevice = WidgetInputDevice.Gamepads | WidgetInputDevice.Keyboard | WidgetInputDevice.Mouse | WidgetInputDevice.Touch;
				}
				else
				{
					playersDatum.InputDevice = WidgetInputDevice.None;
				}
			}
			if (num == 0)
			{
				ScreensManager.SwitchScreen("Player", PlayerScreen.Mode.Initial, GameManager.Project);
			}
			else
			{
				ScreensManager.SwitchScreen("Game");
			}
		}

		[CompilerGenerated]
		private void _003C_002Ector_003Eb__3_2()
		{
			NetworkManager.Listener.NetworkErrorEvent += _003C_003Ec._003C_003E9__3_3 ?? (_003C_003Ec._003C_003E9__3_3 = new EventBasedNetListener.OnNetworkError(_003C_003Ec._003C_003E9._003C_002Ector_003Eb__3_3));
			IPEndPoint serverEndPoint = m_serverEndPoint;
			Log.Information("Connecting to server: " + ((serverEndPoint != null) ? serverEndPoint.ToString() : null));
			NetworkManager.ClientStage = NetworkManager.PeerStage.DownloadingWorld;
			NetworkManager.SendConnectionRequest(m_serverEndPoint);
		}
	}
}
